package com.zang.blogz.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zang.blogz.constant.CommonConstant;
import com.zang.blogz.constant.PublicConstant;
import com.zang.blogz.entity.Article;
import com.zang.blogz.entity.Category;
import com.zang.blogz.entity.Comment;
import com.zang.blogz.entity.Message;
import com.zang.blogz.entity.OperationLog;
import com.zang.blogz.entity.Tag;
import com.zang.blogz.entity.WebsiteConfig;
import com.zang.blogz.model.dto.MapValueDTO;
import com.zang.blogz.model.output.BlogVO;
import com.zang.blogz.service.ArticleService;
import com.zang.blogz.service.BlogService;
import com.zang.blogz.service.MessageService;
import com.zang.blogz.service.UserInfoService;

import io.github.vampireachao.stream.core.collector.Collective;
import io.github.vampireachao.stream.core.stream.EntrySteam;
import io.github.vampireachao.stream.core.stream.Steam;
import io.github.vampireachao.stream.plugin.mybatisplus.Many;
import io.github.vampireachao.stream.plugin.mybatisplus.One;

/**
 * @author Cizai
 * @since 2022/12/11 20:00
 **/
@Service
public class BlogServiceImpl implements BlogService {


    @Autowired
    private ArticleService articleService;

    @Autowired
    private MessageService messageService;

    @Autowired
    private UserInfoService userInfoService;

    @Override
    public BlogVO getBlogInfo() {
        final BlogVO blogVO = new BlogVO();
        final Long aLong = One.of(WebsiteConfig::getId).eq(PublicConstant.ONE).value(WebsiteConfig::getViewCount).query();

        blogVO.setAccessNum(Math.toIntExact(aLong));
        blogVO.setArticleNum(Math.toIntExact(articleService.count(null)));
        blogVO.setMessageNum(Math.toIntExact(messageService.count(null)));
        blogVO.setUserNum(Math.toIntExact(userInfoService.count(null)));
        blogVO.setComments(Many.of(Comment::getId).condition(w -> w.orderByDesc(Comment::getCreateTime).last("limit 5")).query());
        blogVO.setOperateLogs(Many.of(OperationLog::getId).condition(w -> w.orderByDesc(OperationLog:: getCreateTime).last("limit 5")).query());
        blogVO.setTags(Many.of(Tag::getId).value(Tag::getTagName).query());
        final Map<Integer, Long> articlesMap = Many.of(Article::getCategoryId).value(Article::getCategoryId).query(s -> s.group(Function.identity(), Collective.collectingAndThen(Collective.toList(), a -> Steam.of(a).count())));
        final Map<Integer, String> categoryIdMap = Many.of(Category::getId).query(s -> s.toMap(Category::getId, Category::getCategoryName));
        final ArrayList<MapValueDTO> mapValueList = new ArrayList<>();
        EntrySteam.of(categoryIdMap).forEach((key,value) -> {
            final MapValueDTO mapValueDTO = new MapValueDTO();
            mapValueDTO.setName(value);
            final Long aL = articlesMap.get(key);
            mapValueDTO.setValue(aL == null ? 0 : aL);
            mapValueList.add(mapValueDTO);
        });
        blogVO.setMessages(Many.of(Message::getId).condition(w -> w.orderByDesc(Message::getCreateTime).last("limit 5")).query());
        blogVO.setCategories(mapValueList);
        return blogVO;

    }
}
